//package java_cup.runtime;

//import java.util.Dictionary;
//import java.util.List;

public class SyntaxTreeDFS {
    public interface ElementHandler {
        public void handle(XMLElement parent, List<XMLElement> children);
    }

    public abstract class AbstractVisitor : Visitor {
        public Dictionary<String, ElementHandler> preMap = new();
        public Dictionary<String, ElementHandler> postMap = new();

        public abstract void defaultPre(XMLElement element, List<XMLElement> children);

        public abstract void defaultPost(XMLElement element, List<XMLElement> children);

        /*@Override*/
        public void preVisit(XMLElement element) {
            ElementHandler handler = preMap[element.tagname];
            if (handler == null) {
                defaultPre(element, element.getChildren());
            }
            else
                handler.handle(element, element.getChildren());
        }

        /*@Override*/
        public void postVisit(XMLElement element) {
            ElementHandler handler = postMap[element.tagname];
            if (handler == null) {
                defaultPost(element, element.getChildren());
            }
            else
                handler.handle(element, element.getChildren());
        }

        public void registerPreVisit(String s, ElementHandler h) {
            preMap.Add(s, h);
        }

        public void registerPostVisit(String s, ElementHandler h) {
            postMap.Add(s, h);
        }
    }

    public interface Visitor {
        public void preVisit(XMLElement element);

        public void postVisit(XMLElement element);
    }

    public static void dfs(XMLElement element, Visitor visitor) {
        visitor.preVisit(element);
        foreach (XMLElement el in element.getChildren()) {
            dfs(el, visitor);
        }
        visitor.postVisit(element);
    }
}
